import router from '@/router'
import { ElMessageBox, ElMessage } from 'element-plus'
import axios from 'axios'
import isIdCardFunc from "@/utils/isIdCard.js";
import JSZip from 'jszip';//文件压缩
import * as XLSX from 'xlsx';
// import { gaoDeKey } from "@/config/index.js";

export default {
  //discount显示函数
  displayDiscountPercent(p) {
    let rem = Math.floor(p / 100)
    if (rem >= 10) {
      return (rem % 10 == 0) ? (rem / 10) : rem
    } else {
      return '0.' + rem
    }
  },

  //js 精度问题
  precise(a, b, op) {
    // 将参数转换为整数,以防止精度丢失
    a = BigInt(Math.round(Number(a) * 1000000))
    b = BigInt(Math.round(Number(b) * 1000000))

    let result;
    switch (op) {
      case '+':
        result = a + b
        break
      case '-':
        result = a - b
        break
      case '*':
        result = a * b
        break
      case '/':
        result = a / b
        break
    }
    // 将结果转换回浮点数并格式化显示
    return Number(result) / 1000000
  },

  // 保留小数点后两位
  cutOutNum(t) {
    return t.toString().match(/^\d*(\.?\d{0,2})/g)[0] || null
  },

  // 获取斜杠后面的内容
  substringFn(t) {
    var htmlHref = t
    htmlHref = htmlHref.replace(/^http:\/\/[^/]+/, '')
    var addr = htmlHref.substr(
      htmlHref.lastIndexOf('/', htmlHref.lastIndexOf('/') - 1) + 1
    )
    var index = addr.lastIndexOf('/')
    //js 获取字符串中最后一个斜杠后面的内容
    var addrLast = decodeURI(addr.substring(index + 1, addr.length))
    return addrLast
  },

  // 时间格式化
  dateTimeFormateFn(date, type) {
    if (!date) return
    var d = new Date(date);
    d = d.getFullYear() > 0 ? d : new Date(Date.parse(date.replace(/-/g, "/")));        //为了兼容ios
    var year = d.getFullYear();
    var month = ('0' + (d.getMonth() + 1)).slice(-2);
    var day = ('0' + (d.getDate())).slice(-2);
    var hour = ('0' + (d.getHours())).slice(-2);
    var minutes = ('0' + (d.getMinutes())).slice(-2);
    var seconds = ('0' + (d.getSeconds())).slice(-2);
    switch (type) {
      case 'all':
        return `${year}-${month}-${day} ${hour}:${minutes}:${seconds}`
      case 'dayMinutes':
        return `${month}.${day} ${hour}:${minutes}`;
      case 'time':
        return `${hour}:${minutes}:${seconds}`
      case 'year':
        return year
      case 'month':
        return month
      case 'day':
        return day
      case 'monthDate':
        return `${month}-${day}`;
      case 'yearMonth':
        return `${year}-${month}`;
      case 'hourMinutesSeconds':
        return `${hour}:${minutes}:${seconds}`;
      case 'hourMinutes':
        return `${hour}:${minutes}`;
      default:
        return `${year}-${month}-${day}`;
    }
  },

  // 取随机数
  randomNum(maxNum, minNum, decimalNum) {
    // 获取指定范围内的随机数, decimalNum指小数保留多少位
    var max = 0,
      min = 0;
    minNum <= maxNum ? (min = minNum, max = maxNum) : (min = maxNum, max = minNum);
    switch (arguments.length) {
      case 1:
        return Math.floor(Math.random() * (max + 1));
      case 2:
        return Math.floor(Math.random() * (max - min + 1) + min);
      case 3:
        return (Math.random() * (max - min) + min).toFixed(decimalNum);
      default:
        return Math.random();
    }
  },

  //获取页面中某元素的绝对坐标位置
  // 获取顶部div的距离
  getParentTop(e) {
    var offset = e.offsetTop
    if (e.offsetParent != null) {
      offset += this.getParentTop(e.offsetParent)
    }
    return offset
  },

  // 获取左侧div的距离
  getParentLeft(e) {
    var offset = e.offsetLeft
    if (e.offsetParent != null) {
      offset += this.getParentLeft(e.offsetParent)
    }
    return offset
  },

  //打乱数组顺序
  shuffle(array) {
    let counter = array.length;

    // While there are elements in the array
    while (counter > 0) {
      // Pick a random index
      let index = Math.floor(Math.random() * counter);

      // Decrease counter by 1
      counter--;

      // And swap the last element with it
      let temp = array[counter];
      array[counter] = array[index];
      array[index] = temp;
    }

    return array;
  },

  // 将数字取整为10的倍数
  //   @param {Number} num 需要取整的值
  //  * @param {Boolean} ceil 是否向上取整
  //  * @param {Number} prec 需要用0占位的数量
  formatInt(num, prec = 2, ceil = false) {
    const len = String(num).length;
    if (len <= prec) { return num };

    const mult = Math.pow(10, prec);
    return ceil ?
      Math.ceil(num / mult) * mult :
      Math.floor(num / mult) * mult;
  },

  // 判断Json是否为空
  isEmptyObject(data) {
    let arr = Object.keys(data);
    if (arr.length == 0) {
      return true
    } else {
      return false
    }
  },

  //判断是不是微信打开
  isWeiXin() {
    const ua = window.navigator.userAgent
    return ua.match(/MicroMessenger/i) == 'MicroMessenger'
  },

  //判断是不是正确的邮箱格式
  isValidEmail(email) {
    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailPattern.test(email);
  },

  //对象里面的值都清空
  objValueIsEmpty(form) {
    for (let key in form) {
      form[key] = ''
    }
    return form
  },

  //将阿拉伯数字翻译成中文的大写数字
  numberToChinese(num) {
    var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十");
    var BB = new Array("", "十", "百", "仟", "萬", "億", "点", "");
    var a = ("" + num).replace(/(^0*)/g, "").split("."),
      k = 0,
      re = "";
    for (var i = a[0].length - 1; i >= 0; i--) {
      switch (k) {
        case 0:
          re = BB[7] + re;
          break;
        case 4:
          if (!new RegExp("0{4}//d{" + (a[0].length - i - 1) + "}$")
            .test(a[0]))
            re = BB[4] + re;
          break;
        case 8:
          re = BB[5] + re;
          BB[7] = BB[5];
          k = 0;
          break;
      }
      if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)
        re = AA[0] + re;
      if (a[0].charAt(i) != 0)
        re = AA[a[0].charAt(i)] + BB[k % 4] + re;
      k++;
    }

    if (a.length > 1) // 加上小数部分(如果有小数部分)
    {
      re += BB[6];
      for (var i = 0; i < a[1].length; i++)
        re += AA[a[1].charAt(i)];
    }
    if (re == '一十')
      re = "十";
    if (re.match(/^一/) && re.length == 3)
      re = re.replace("一", "");
    return re;
  },

  //多维数组得深拷贝
  deepcopy(obj) {
    return JSON.parse(JSON.stringify(obj))
  },

  //对象转成数组
  objTurnArr(obj) {
    return Object.entries(obj).map(([key, value]) => ({
      label: key,
      value: value
    }));
  },

  //对象深拷贝函数 (异步，需要配合async和await)
  structuralClone(obj) {
    return new Promise(resolve => {
      const { port1, port2 } = new MessageChannel()
      port2.onmessage = ev => resolve(ev.data)
      port1.postMessage(obj)
    })
  },

  //第一个对象取值 给第二个对象赋值
  formatFunction(param1, param2) {
    Object.keys(param2).forEach(function(v) {
      if (Object.prototype.hasOwnProperty.call(param1, v)) {
        param2[v] = param1[v];
      }
    });
    return param2;
  },

  //判断是不是数字
  isNumber(val) {
    // isNaN()函数 把空串 空格 以及NUll 按照0来处理 所以先去除，
    if (val === "" || val == null) {
      return false;
    }
    if (!isNaN(val)) {
      //对于空数组和只有一个数值成员的数组或全是数字组成的字符串，isNaN返回false，例如：'123'、[]、[2]、['123'],isNaN返回false,
      //所以如果不需要val包含这些特殊情况，则这个判断改写为if(!isNaN(val) && typeof val === 'number' )
      return true;
    }
    else {
      return false;
    }
  },

  //str:原始字符串，index,开始位置,changeStr，改变后的字
  changeStr(str, index, changeStr) {
    return str.substr(0, index) + changeStr + str.substr(index + changeStr.length);
  },

  //身份证号或者手机号等等字符串想实现替换中间几位字符串
  replacepos(text, start, stop, replacetext) {
    let mystr = text.substr(0, start - 1) + replacetext + text.substr(stop + 1);
    return mystr;
  },

  //将个位数补成十位数
  p(s) {
    return s < 10 ? '0' + s : s
  },

  //获取上个月      获取当前 yy - mm - dd
  getPreMonth(date) {
    var arr = date.split('-');
    var year = arr[0]; //获取当前日期的年份  
    var month = arr[1]; //获取当前日期的月份  
    var day = arr[2]; //获取当前日期的日  
    var days = new Date(year, month, 0);
    days = days.getDate(); //获取当前日期中月的天数  
    var year2 = year;
    var month2 = parseInt(month) - 1;
    if (month2 == 0) {
      year2 = parseInt(year2) - 1;
      month2 = 12;
    }
    var day2 = day;
    var days2 = new Date(year2, month2, 0);
    days2 = days2.getDate();
    if (day2 > days2) {
      day2 = days2;
    }
    if (month2 < 10) {
      month2 = '0' + month2;
    }
    var t2 = year2 + '-' + month2 + '-' + day2;
    return t2;
  },

  //获取下个月日期    获取当前 yy - mm - dd
  getNextMonth(date) {
    var arr = date.split('-');
    var year = arr[0]; //获取当前日期的年份  
    var month = arr[1]; //获取当前日期的月份  
    var day = arr[2]; //获取当前日期的日  
    var days = new Date(year, month, 0);
    days = days.getDate(); //获取当前日期中的月的天数  
    var year2 = year;
    var month2 = parseInt(month) + 1;
    if (month2 == 13) {
      year2 = parseInt(year2) + 1;
      month2 = 1;
    }
    var day2 = day;
    var days2 = new Date(year2, month2, 0);
    days2 = days2.getDate();
    if (day2 > days2) {
      day2 = days2;
    }
    if (month2 < 10) {
      month2 = '0' + month2;
    }

    var t2 = year2 + '-' + month2 + '-' + day2;
    return t2;
  },

  //这是比较函数 升序  p是某一属性值,如果有sort，那就是降序     使用：arr.sort(compare('age'))
  compare(p, sort) {
    return function(m, n) {
      var a = m[p];
      var b = n[p];
      if (sort) {
        return b - a; //降序
      } else {
        return a - b; //升序
      }
    }
  },

  //判断一个值，距离数组里面的哪个值更接近  数组无序的情况，从头查找
  limit(arr, num) {
    var ret = arr[0];
    var distance = Math.abs(ret - num);
    for (var i = 1; i < arr.length; i++) {
      var newDistance = Math.abs(arr[i] - num);
      if (newDistance < distance) {
        distance = newDistance;
        ret = arr[i];
      }
    }
    return ret;
  },

  //判断一个值，距离数组里面的哪个值更接近  数组有序的情况，二分查找
  closest(arr, num) {
    var left = 0;
    var right = arr.length - 1;

    while (left <= right) {
      var middle = Math.floor((right + left) / 2);
      if (right - left <= 1) {
        break;
      }
      var val = arr[middle];
      if (val === num) {
        return middle;
      }
      else if (val > num) {
        right = middle;
      }
      else {
        left = middle;
      }
    }
    var leftValue = arr[left];
    var rightValue = arr[right];
    return rightValue - num > num - leftValue ? leftValue : rightValue;
  },

  //保留两位小数（不四舍五入）  num是数字  decimal是保留几位小数
  formatDecimal(num, decimal) {
    num = num.toString()
    let index = num.indexOf('.')
    if (index !== -1) {
      num = num.substring(0, decimal + index + 1)
    } else {
      num = num.substring(0)
    }
    return parseFloat(num).toFixed(decimal)
  },

  // js数组根据对象中的元素去重
  arrayUnique2(arr, name) {
    var hash = {};
    return arr.reduce(function(item, next) {
      hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
      return item;
    }, []);
  },

  //判断两个对象是否相等
  isObjectValueEqual(a, b) {
    //取对象a和b的属性名
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);
    //判断属性名的length是否一致
    if (aProps.length != bProps.length) {
      return false;
    }
    //循环取出属性名，再判断属性值是否一致
    for (var i = 0; i < aProps.length; i++) {
      var propName = aProps[i];
      if (a[propName] !== b[propName]) {
        return false;
      }
    }
    return true;
  },

  //判断两个 json 数组是否相等
  arraysAreEqual(arr1, arr2) {
    if (arr1.length !== arr2.length) {
      return false;
    }
    arr1.sort();
    arr2.sort();
    for (let i = 0; i < arr1.length; i++) {
      if (JSON.stringify(arr1[i]) !== JSON.stringify(arr2[i])) {
        return false;
      }
    }
    return true;
  },

  //判断两个数组是否完全一致
  arraysEqual(arr1, arr2) {
    // 首先检查两个数组的长度
    if (arr1.length !== arr2.length) {
      return false;
    }
    // 检查每一项是否相等
    return arr1.every((value, index) => value === arr2[index]);
  },


  //分钟数 转换成 小时数
  ChangeHourMinutestr(str) {
    if (!str) return '00:00'
    if (str !== "0" && str !== "" && str !== null) {
      return ((Math.floor(str / 60)).toString().length < 2 ? "0" + (Math.floor(str / 60)).toString() :
        (Math.floor(str / 60)).toString()) + ":" + ((str % 60).toString().length < 2 ? "0" + (str % 60).toString() : (str % 60).toString());
    }
  },

  //小时分钟格式转换为分钟数
  ChangeStrToMinutes(str) {
    var arrminutes = str.split(":");
    if (arrminutes.length == 2) {
      var minutes = parseInt(arrminutes[0]) * 60 + parseInt(arrminutes[1]);
      return minutes;
    }
    else {
      return 0;
    }
  },

  //两数组比较,取相同的值组成新的数组
  getCommonElements(arr1, arr2) {
    return arr1.filter(item => arr2.includes(item));
  },

  //两数组比较，取不同的值组成新的数组
  takeNewArray(list1, list2) {
    let newArr = []
    list1.forEach((item, index) => {
      var isExist = false;
      list2.forEach(m => {
        if (item == m) {
          isExist = true;
          return false;
        }
      })
      if (!isExist) {
        newArr.push(item)
      }
    })
    return newArr
  },

  // 数组去重
  unique(arr) {
    for (var i = 0; i < arr.length; i++) {
      for (var j = i + 1; j < arr.length; j++) {
        if (arr[i] == arr[j]) {         //第一个等同于第二个，splice方法删除第二个
          arr.splice(j, 1);
          j--;
        }
      }
    }
    return arr;
  },

  //去除一个数组中与另一个数组中的值相同的元素
  array_diff(a, b) {
    let list = a.filter(items => {
      if (!b.includes(items)) return items;
    })
    return list;
  },

  //生成唯一key
  generateUUID() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
  },

  // 纯数字的唯一id
  getNumberId() {
    var str = '';
    for (var i = 0; i < 7; i += 1) {
      str += Math.floor(Math.random() * 10);
    }
    return str;
  },

  //两个日期之间相差的天数
  getDaysBetween(dateString1, dateString2) {
    var startDate = Date.parse(dateString1);
    var endDate = Date.parse(dateString2);
    var days = (endDate - startDate) / (1 * 24 * 60 * 60 * 1000);
    // alert(days);
    return days;
  },

  //判断是数组还是obj
  isObjArr(value) {
    if (Object.prototype.toString.call(value) === "[object Array]") {
      console.log('value是数组');
    } else if (Object.prototype.toString.call(value) === '[object Object]') {
      console.log('value是对象');
    } else {
      console.log('value不是数组也不是对象')
    }
  },

  //函数判断是不是obj对象
  isObject(obj) {
    return obj instanceof Object;
  },

  //获取两日期之间日期列表函数   2018-07-25
  getdiffdate(stime, etime) {
    //初始化日期列表，数组
    var diffdate = new Array();
    var i = 0;
    //开始日期小于等于结束日期,并循环
    while (stime <= etime) {
      diffdate[i] = stime;

      //获取开始日期时间戳
      var stime_ts = new Date(stime).getTime();

      //增加一天时间戳后的日期
      var next_date = stime_ts + (24 * 60 * 60 * 1000);

      //拼接年月日，这里的月份会返回（0-11），所以要+1
      var next_dates_y = new Date(next_date).getFullYear() + '-';
      var next_dates_m = (new Date(next_date).getMonth() + 1 < 10) ? '0' + (new Date(next_date).getMonth() + 1) + '-' : (new Date(next_date).getMonth() + 1) + '-';
      var next_dates_d = (new Date(next_date).getDate() < 10) ? '0' + new Date(next_date).getDate() : new Date(next_date).getDate();

      stime = next_dates_y + next_dates_m + next_dates_d;

      //增加数组key
      i++;
    }
    return diffdate
  },


  //将分钟转成时分格式
  toHourMinute(minutes) {
    function p(s) {
      return s < 10 ? '0' + s : s
    }
    return (p(Math.floor(minutes / 60)) + ":" + p(minutes % 60));
    // 也可以转换为json，以方便专外部使用属
    // return {hour:Math.floor(minutes/60),minute:(minutes%60)};
  },

  //获取给定月份N月后的日期   date:当前日期   num：N月后
  getNmonthDate(date, num) {
    var d = new Date(date);
    // 因为getMonth()获取的月份的值只能在0~11之间所以我们在进行setMonth()之前先给其减一
    d.setMonth((d.getMonth() - 1) + (num + 1));
    var yy1 = d.getFullYear();
    var mm1 = d.getMonth() + 1;
    var dd1 = d.getDate();
    if (mm1 < 10) {
      mm1 = '0' + mm1;
    }
    if (dd1 < 10) {
      dd1 = '0' + dd1;
    }
    return `${yy1}-${mm1}-${dd1}`
  },

  //获取当前月份的第一天
  getCurrentMonthFirst() {
    var date = new Date();
    date.setDate(1);
    var month = parseInt(date.getMonth() + 1);
    var day = date.getDate();
    if (month < 10) {
      month = '0' + month
    }
    if (day < 10) {
      day = '0' + day
    }
    return date.getFullYear() + '-' + month + '-' + day;
  },

  //获取当前月份的最后一天
  getCurrentMonthLast() {
    var date = new Date();
    var currentMonth = date.getMonth();
    var nextMonth = ++currentMonth;
    var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
    var oneDay = 1000 * 60 * 60 * 24;
    var lastTime = new Date(nextMonthFirstDay - oneDay);
    var month = parseInt(lastTime.getMonth() + 1);
    var day = lastTime.getDate();
    if (month < 10) {
      month = '0' + month
    }
    if (day < 10) {
      day = '0' + day
    }
    return date.getFullYear() + '-' + month + '-' + day;
  },

  //返回上一层
  goBack() {
    return router.go(-1);
  },

  //判断是不是字符串
  isString(str) {
    return (typeof str == 'string') && str.constructor == String;
  },

  //判断是不是数组或者是 json 数组
  isArrayOrJsonArray(variable) {
    // 判断是否是数组
    if (Array.isArray(variable)) {
      return true;
    }

    // 判断是否是对象并且是数组格式的 JSON
    if (typeof variable === 'object' && variable !== null) {
      return Object.keys(variable).length > 0 && variable.constructor === Object;
    }

    return false;
  },

  //计算两个日期的间隔时间（时间差）  小时.分钟
  getHoursDiff(dt1, dt2) {
    if (typeof (dt1) == "string") {
      dt1 = new Date(dt1.replace(/-/, '/'));
      dt2 = new Date(dt2.replace(/-/, '/'));
      var res = dt2 - dt1;
      if (isNaN(res))
        throw Error("invalid dates arguments");
      let re = res / (1000 * 60 * 60);
      var h = parseInt(re);
      var m = parseInt((re - h) * 60);
      return `${h}.${m}`
    }
  },

  //获取符号前面的数值
  substringFn(ab, symbol) {  //ab 要截取的内容   symbol：符号
    var ab_str = ab.toString();
    return parseInt(ab_str.substring(0, ab_str.indexOf(symbol)));
  },

  //计算两个日期的时间间隔（天，时，分，秒）
  getIntervalTime(s, e) {
    let startTime = new Date(s); // 开始时间
    let endTime = new Date(e); // 结束时间
    let usedTime = endTime - startTime; // 相差的毫秒数
    let days = Math.floor(usedTime / (24 * 3600 * 1000)); // 计算出天数
    let leavel = usedTime % (24 * 3600 * 1000); // 计算天数后剩余的时间
    let hours = Math.floor(leavel / (3600 * 1000)); // 计算剩余的小时数
    let leavel2 = leavel % (3600 * 1000); // 计算剩余小时后剩余的毫秒数
    let minutes = Math.floor(leavel2 / (60 * 1000)); // 计算剩余的分钟数
    return days + '天' + hours + '时' + minutes + '分';
  },

  //js格式化分钟转为天、时、分
  formatMinutes(StatusMinute) {
    var day = parseInt(StatusMinute / 60 / 24);
    var hour = parseInt(StatusMinute / 60 % 24);
    var min = parseInt(StatusMinute % 60);
    StatusMinute = "";
    if (day > 0) {
      StatusMinute = day + "天";
    }
    if (hour > 0) {
      StatusMinute += hour + "小时";
    }
    if (min > 0) {
      StatusMinute += parseFloat(min) + "分钟";
    }
    //三元运算符 传入的分钟数不够一分钟 默认为0分钟，else return 运算后的StatusMinute 
    return StatusMinute == "" ? "0分钟" : StatusMinute;
  },

  //加法
  accAdd(arg1, arg2) {
    var r1, r2, m;
    try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
    try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
    m = Math.pow(10, Math.max(r1, r2))
    return (arg1 * m + arg2 * m) / m
  },

  //判断是移动端还是pc端
  isMobile() {
    let flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
    return flag;
  },

  //时间转时间戳
  getTimeFn(t) {
    if (t) {
      return new Date(t.replace(/-/g, "/")).getTime()
    } else {
      return new Date().getTime()
    }
  },

  //获取两个月份之间的所有月份，可以跨年选择   getYearAndMonth("2018-05","2019-06");
  getYearAndMonth(start, end) {
    if (!start || !end) return
    var result = [];
    var newResult = [];
    var starts = start.split('-');
    var ends = end.split('-');
    var staYear = parseInt(starts[0]);
    var staMon = parseInt(starts[1]);
    var endYear = parseInt(ends[0]);
    var endMon = parseInt(ends[1]);
    while (staYear <= endYear) {
      if (staYear === endYear) {
        while (staMon < endMon) {
          staMon++;
          result.push({ year: staYear, month: staMon, dateTime: `${staYear}-${this.p(staMon)}` });
        }
        staYear++;
      } else {
        staMon++;
        if (staMon > 12) {
          staMon = 1;
          staYear++;
        }
        result.push({ year: staYear, month: staMon, dateTime: `${staYear}-${this.p(staMon)}` });
      }
    }

    for (var i = 0; i < result.length; i++) {
      var year = result[i].year;
      var monthinit = result[i].month;
      if (monthinit < 10) {
        var month = `0${monthinit}`;
      } else {
        var month = monthinit;
      }
      // var ym = year + '' + month + '';
      var ym = `${year}-${month}`;
      newResult.push(ym);
    }
    //newResult.unshift(start.replace(/-/g, ''));//正则去掉横线
    // console.log('result', result);
    // console.log('newResult', newResult);

    return result;
  },

  //获取两个月份之间的所有月份，可以跨年选择(包含第一个月)
  listMonths(startDate, endDate) {
    const months = [];
    let currentDate = new Date(startDate);
    endDate = new Date(endDate);

    while (currentDate <= endDate) {
      const year = currentDate.getFullYear();
      const month = currentDate.getMonth() + 1;
      const monthString = `${year}-${month.toString().padStart(2, '0')}`;
      months.push(monthString);

      currentDate.setMonth(currentDate.getMonth() + 1);
    }

    return months;
  },

  //判断2023-11-01和2023-11-30是否是一个月的头和尾
  isSameMonthStartAndEnd(date1, date2) {
    const d1 = new Date(date1);
    const d2 = new Date(date2);
    return (
      d1.getFullYear() === d2.getFullYear() &&
      d1.getMonth() === d2.getMonth() &&
      d1.getDate() === 1 &&
      d2.getDate() === new Date(d2.getFullYear(), d2.getMonth() + 1, 0).getDate()
    );
  },

  //根据数组对象中相同属性值组建新数组
  sameSortArr(beforeData, name) {
    let afterData = [];
    let tempArr = [];
    for (let i = 0; i < beforeData.length; i++) {
      if (tempArr.indexOf(beforeData[i][name]) == -1) {
        afterData.push({
          name: beforeData[i][name],
          origin: [beforeData[i]]
        });
        tempArr.push(beforeData[i][name]);
      } else {
        for (let j = 0; j < afterData.length; j++) {
          if (afterData[j].name == beforeData[i][name]) {
            afterData[j].origin.push(beforeData[i]);
            break;
          }
        }
      }
    }
    return afterData
  },

  // Build a URL with query arguments
  buildUrl(base, queries) {
    let ret = base
    if (typeof (queries) == 'undefined') return ret
    let isFirst = true
    for (let key in queries) {
      let value = queries[key]
      if (isFirst) {
        ret += '?'
        isFirst = false
      } else {
        ret += '&'
      }
      if (typeof (value) == 'undefined' || value === null) {
        ret += key
      } else {
        // ret += key + '=' + encodeURIComponent(value)
        ret += key + '=' + value
      }
    }
    return ret
  },


  //获取当前所在周的周六、周日
  getWeekDay(date) {
    let _date
    if (date) {
      _date = new Date(date);
    } else {
      _date = new Date();
    }
    let _nowTime = _date.getTime();
    let _week = _date.getDay();
    let _dayLongTime = 24 * 60 * 60 * 1000;
    let _furtureSundayTimes = _nowTime + (7 - _week) * _dayLongTime;
    let _furtureSaturdayTimes = _nowTime + (6 - _week) * _dayLongTime;
    _furtureSundayTimes = new Date(_furtureSundayTimes);
    _furtureSaturdayTimes = new Date(_furtureSaturdayTimes);
    // staurday
    let _satYear = _furtureSaturdayTimes.getFullYear();
    let _satMonth = _furtureSaturdayTimes.getMonth() + 1;
    let _satDay = _furtureSaturdayTimes.getDate();
    //sunday
    let _sunYear = _furtureSundayTimes.getFullYear();
    let _sunMonth = _furtureSundayTimes.getMonth() + 1;
    let _sunDay = _furtureSundayTimes.getDate();
    _satMonth = _satMonth >= 10 ? _satMonth : '0' + _satMonth;
    _satDay = _satDay >= 10 ? _satDay : '0' + _satDay;
    _sunMonth = _sunMonth >= 10 ? _sunMonth : '0' + _sunMonth;
    _sunDay = _sunDay >= 10 ? _sunDay : '0' + _sunDay;
    let _mealSunDay = _satYear + '-' + _satMonth + '-' + _satDay;
    let _mealSaturDay = _sunYear + '-' + _sunMonth + '-' + _sunDay;
    let _weekendDay = {
      saturDay: _mealSunDay,
      sunDay: _mealSaturDay
    }
    return _weekendDay;
  },

  //根据传入的日期判读是当年的第xx周
  getWeekInYear(date) {
    function getWeekStartByDate(date) {
      date = new Date(date)
      let day = date.getDay()
      return getDateFromDay(date, -day)
    }
    function getDateFromDay(dayDate, day) {
      let date = new Date()
      date.setTime(dayDate.getTime() + day * 24 * 60 * 60 * 1000)
      return date
    }
    //console.log(date)
    //判断该星期是否跨年，如果跨年就是第一周
    let weekStartDate = getWeekStartByDate(date) //一周开始时间
    //console.log(weekStartDate, 'weekStartDate')
    let endDate = getDateFromDay(weekStartDate, 6) //一周结束时间
    //console.log(endDate, 'endDate')
    if (weekStartDate.getFullYear() != endDate.getFullYear()) {
      //console.log(endDate.getFullYear() + '年第1周')
      let num = 1
      return num
    }
    let d1 = new Date(date)
    let d2 = new Date(date)
    d2.setMonth(0)
    d2.setDate(1)
    d2 = getWeekStartByDate(d2)
    //console.log(d2, 'd2')
    let rq = d1 - d2
    let days = Math.ceil(rq / (24 * 60 * 60 * 1000)) + 1
    let num = Math.ceil(days / 7)
    //console.log(endDate.getFullYear() + '年第' + num + '周')
    return num
  },


  //判断两个日期是否在同一个月
  twoDateIsSameMonth(dt1, dt2) {
    dt1 = new Date(dt1.replace(/-/g, "/"));
    dt2 = new Date(dt2.replace(/-/g, "/"));
    if (dt1.getFullYear() == dt2.getFullYear() && dt1.getMonth() == dt2.getMonth()) return true
    return false
  },

  //路由跳转
  toLink(result) {
    const isHashMode = window.location.hash.length > 0;
    if (isHashMode) {
      window.location.hash = result
    } else {
      router.push(result)
    }
  },

  // JS 计算两个时间戳相差年月日时分秒
  calculateDiffTime(startTime, endTime, type) {
    var runTime = parseInt(endTime - startTime)
    var year = Math.floor(runTime / 86400 / 365)
    runTime = runTime % (86400 * 365)
    var month = Math.floor(runTime / 86400 / 30)
    runTime = runTime % (86400 * 30)
    var day = Math.floor(runTime / 86400)
    runTime = runTime % 86400
    var hour = Math.floor(runTime / 3600)
    runTime = runTime % 3600
    var minute = Math.floor(runTime / 60)
    runTime = runTime % 60
    var second = runTime
    if (type === 1) { // 返回相差年数
      return year + '年'
    } else if (type === 2) { // 返回相差年数月数
      return year + '年' + month + '月'
    } else if (type === 3) { // 返回相差年数月数天数
      return year + '年' + month + '月' + day + '日'
    } else { // 返回相差年数月数天数时分秒
      return year + '年' + month + '月' + day + '日' + hour + '时' + minute + '分' + second + '秒'
    }
  },

  //计算两个日期之间的月数
  datemonth(date1, date2) {
    // 拆分年月日
    date1 = date1.split('-');
    // 得到月数
    date1 = parseInt(date1[0]) * 12 + parseInt(date1[1]);
    // 拆分年月日
    date2 = date2.split('-');
    // 得到月数
    date2 = parseInt(date2[0]) * 12 + parseInt(date2[1]);
    var m = Math.abs(date1 - date2); //Math.abs()取绝对值
    return m;
  },

  //比较2个字符串内元素的不同(字符1, 字符2, 分隔符可选)
  stringDiff(str1, str2, separator) {
    //
    str1 = str1 || "";
    str2 = str2 || "";
    separator = separator || ",";
    // arr中有ele元素
    function hasElement(arr, ele) {
      // 内存循环
      var hasItem1 = false;
      for (var i2 = 0; i2 < arr.length; i2++) {
        //
        var item2 = arr[i2] || "";
        if (!item2) {
          continue;
        }
        //
        if (ele == item2) {
          hasItem1 = true;
          break;
        }
      }
      return hasItem1;
    };
    function inAnotB(a, b) { // 在A中，不在B中
      var res = [];
      for (var i1 = 0; i1 < a.length; i1++) {
        var item1 = a[i1] || "";
        if (!item1) {
          continue;
        }
        var hasItem1 = hasElement(b, item1);
        if (!hasItem1) {
          res.push(item1);
        }
      }
      return res;
    };
    //
    var list1 = str1.split(",");
    var list2 = str2.split(",");
    //
    var diff1 = inAnotB(list1, list2);
    var diff2 = inAnotB(list2, list1);

    // 返回结果
    var result = {
      diff1: diff1
      ,
      diff2: diff2
      ,
      separator: separator
      ,
      toString: function() {
        //
        var res = this["diff1"].slice(0);
        res = res.concat(this["diff2"]);
        //
        return res.join(this["separator"]);
      }
    };
    //
    return result;
  },


  //file转base64
  imageToBase64(file) {
    return new Promise((resolve, reject) => {
      var reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        resolve(reader.result)
      }
      reader.onerror = function(error) {
        reject(error)
      }
    })
  },

  //ElMessageBox vue3
  confirmTips(title) {
    return new Promise((resolve, reject) => {
      ElMessageBox.confirm(
        title,
        '提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }
      )
        .then(() => {
          resolve(true);
        })
        .catch(() => {
          resolve(false);
        })
    });
  },

  //验证车牌号
  isLicenseNo(str) {
    return /(^[\u4E00-\u9FA5]{1}[A-Z0-9]{6}$)|(^[A-Z]{2}[A-Z0-9]{2}[A-Z0-9\u4E00-\u9FA5]{1}[A-Z0-9]{4}$)|(^[\u4E00-\u9FA5]{1}[A-Z0-9]{5}[挂学警军港澳]{1}$)|(^[A-Z]{2}[0-9]{5}$)|(^(08|38){1}[A-Z0-9]{4}[A-Z0-9挂学警军港澳]{1}$)/.test(str);
  },

  //验证字符串是否为手机号
  isPoneAvailable(s) {
    const regex = /^1\d{10}$/;
    return regex.test(s);
  },

  //校验身份证
  isIdCard(idCard) {
    return isIdCardFunc(idCard)
  },

  //判断两个时间段是否相差 m 个月
  completeDate(time1, time2, m) {
    time1 = new Date(time1)
    time2 = new Date(time2)
    var diffyear = time2.getFullYear() - time1.getFullYear();
    var diffmonth = diffyear * 12 + time2.getMonth() - time1.getMonth();
    if (diffmonth < 0) {
      return false;
    }
    var diffDay = time2.getDate() - time1.getDate();
    if (diffmonth < m || (diffmonth == m && diffDay <= 0)) {
      if (diffmonth == m && diffDay == 0) {
        var timeA = time1.getHours() * 3600 + 60 * time1.getMinutes() + time1.getSeconds();
        var timeB = time2.getHours() * 3600 + 60 * time2.getMinutes() + time2.getSeconds();
        if (timeB - timeA > 0) {
          return false;
        }
      }
      return true;
    }
    return false;
  },

  //base64编码
  getEncode64(str) {
    // 对字符串进行编码
    var encode = encodeURI(str);
    // 对编码的字符串转化base64
    var base64 = window.btoa(encode);
    return base64;
  },


  //base64解码
  getDecode(str) {
    // 对base64转编码
    var decode = window.atob(str);
    // 编码转字符串
    var str = decodeURI(decode)
    return str;
  },

  //获取省市区街道
  async getAreas(keywords, subdistrict) {
    //国家、省/直辖市、市、区/县、乡镇/街道多级    0、1、2、3
    let url = this.buildUrl("https://restapi.amap.com/v3/config/district", {
      key: gaoDeKey,
      keywords: keywords ? keywords : "",
      subdistrict: subdistrict ? subdistrict : 3
    })
    let resp = await axios.get(url)
    return resp.data.districts
  },

  //线上文件进行下载
  JSZipDownLoad(attachments, fileName) {
    // 创建一个新的 JSZip 实例
    const zip = new JSZip();

    // 使用 Axios 库下载每个附件，并将其添加到压缩包中
    Promise.all(attachments.map((url) => axios.get(url.path, { responseType: 'blob' })))
      .then((responses) => {
        responses.forEach((response, index) => {
          let { responseURL } = response.request
          let current = this.findIndexByField(attachments, "path", responseURL)
          // 处理每一个文件name
          // 优化后：提取原始扩展名 + 替换非法字符
          const getExtension = (mimeType) => {
            const map = {
              'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
              'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
              'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'pptx',
              'application/pdf': 'pdf',
              'application/msword': 'doc',
              'application/vnd.ms-excel': 'xls',
              'application/vnd.ms-powerpoint': 'ppt',
              'image/jpeg': 'jpg',
              'image/png': 'png',
              'image/gif': 'gif',
              'image/bmp': 'bmp',
              'image/svg+xml': 'svg',
              'image/webp': 'webp',
              'image/x-icon': 'ico',
              'image/tiff': 'tiff',
              'audio/mpeg': 'mp3',
              'audio/wav': 'wav',
              'audio/aac': 'aac',
              'audio/ogg': 'ogg',
              'audio/flac': 'flac',
              'audio/x-ms-wma': 'wma',
              'video/mp4': 'mp4',
              'video/mpeg': 'mpeg',
              'video/x-msvideo': 'avi',
              'video/quicktime': 'mov',
              'video/webm': 'webm',
              'video/x-matroska': 'mkv',
              'application/zip': 'zip',
              'application/vnd.rar': 'rar',
              'application/x-7z-compressed': '7z',
              'application/x-tar': 'tar',
              'application/gzip': 'gz',
              'application/x-bzip2': 'bz2',
              'text/plain': 'txt',
              'text/csv': 'csv',
              'application/xml': 'xml',
              'application/json': 'json',
              'text/html': 'html',
              'text/css': 'css',
              'application/javascript': 'js',
              'application/x-executable': 'exe',
              'application/illustrator': 'ai',
              'application/vnd.autodesk.dwg': 'dwg',
              'font/ttf': 'ttf',
              'font/otf': 'otf',
              'message/rfc822': 'eml',
              'text/markdown': 'md',
              'image/vnd.adobe.photoshop': 'psd',
              'application/vnd.android.package-archive': 'apk',
              'application/x-iso9660-image': 'iso'
            };
            return map[mimeType] || mimeType.split('/').pop(); // 若未定义则回退到原逻辑
          };
          const filename = `${attachments[current].name}.${getExtension(response.headers['content-type'])}`;
          zip.file(filename, response.data);
        });

        // 生成压缩包并将其下载到本地
        zip.generateAsync({ type: 'blob' }).then((content) => {
          const link = document.createElement('a');
          link.href = URL.createObjectURL(content);
          link.download = fileName ? fileName : 'attachments.zip'; // 设置压缩包name
          link.click();
        });
      })
      .catch((error) => {
        console.error(error);
      });
  },

  //金额转成大写
  dealBigMoney(num) {
    if (num == null || num == '' || num == undefined || num == NaN || num == "NaN") return
    if (!this.isNumber(num)) throw new Error('参数为数字')
    let strOutput = ""
    let strUnit = '仟佰拾亿仟佰拾万仟佰拾元角分'
    num += "00"
    const intPos = num.indexOf('.')
    if (intPos >= 0) {
      num = num.substring(0, intPos) + num.substr(intPos + 1, 2)
    }
    strUnit = strUnit.substr(strUnit.length - num.length)
    for (let i = 0; i < num.length; i++) {
      strOutput += '零壹贰叁肆伍陆柒捌玖'.substr(num.substr(i, 1), 1) + strUnit.substr(i, 1)
    }
    return strOutput
      .replace(/零角零分$/, '整')
      .replace(/零[仟佰拾]/g, '零')
      .replace(/零{2,}/g, '零')
      .replace(/零([亿|万])/g, '$1')
      .replace(/零+元/, '元')
      .replace(/亿零{0,3}万/, '亿')
      .replace(/^元/, "零元");
  },

  // resp未接口获得文件流，title是导出的表格文件名
  exportFile(resp, type, title) {
    let BlobType
    switch (type) {
      case "word":
        BlobType = "application/msword"
        break;
      case "excel":
        BlobType = "application/vnd.ms-excel"
        break;
      case "png":
        BlobType = "image/png"
        break;
      default:
        break;
    }
    let blob = new Blob([resp], { type: BlobType }); //type为所需要下载的文件格式，以xls文件为例
    let link = document.createElement('a'); // 创建a标签
    link.style.display = 'none';
    let objectUrl = URL.createObjectURL(blob);
    link.setAttribute('download', title)
    link.href = objectUrl;
    link.click();
    URL.revokeObjectURL(objectUrl);
  },

  //下载 base64 数据
  downloadBase64(base64Data, fileName) {
    // 将 Base64 数据拆分为数据部分和编码类型部分
    let parts = base64Data.split(";base64,");
    let contentType = parts[0].split(":")[1];
    let raw = window.atob(parts[1]);
    let rawLength = raw.length;
    let uInt8Array = new Uint8Array(rawLength);

    // 将 Base64 解码后的二进制数据存储到 Uint8Array 中
    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i);
    }

    // 创建 Blob 对象
    let blob = new Blob([uInt8Array], { type: contentType });
    let url = URL.createObjectURL(blob);

    // 创建下载链接
    let a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  },

  //能根据json数组里面的某一个字段进行查重
  findDuplicatesByField(jsonArray, fieldName) {
    const duplicates = jsonArray.filter((item, index, self) =>
      self.some((otherItem) => item[fieldName] === otherItem[fieldName] && item !== otherItem)
    );
    return duplicates;
  },

  //把一个数组拆分成几个数组
  splitArray(array, size) {
    let data = [];
    for (let i = 0; i < array.length; i += size) {
      data.push(array.slice(i, i + size))
    }
    return data
  },

  //让前端生成唯一key
  generateUniqueKey() {
    const timestamp = new Date().getTime();
    const random = Math.floor(Math.random() * 1000000);
    return `${timestamp}_${random}`;
  },

  //字符串压缩方法
  compress(str) {
    let output = '';
    let counter = 1;

    for (let i = 0; i < str.length; i++) {
      if (str[i] === str[i + 1]) {
        counter++;
      } else {
        output += str[i] + counter;
        counter = 1;
      }
    }
    return output;
  },

  // 解压方法  
  decompress(str) {
    let output = '';
    for (let i = 0; i < str.length; i += 2) {
      let char = str[i];
      let count = str[i + 1];
      output += char.repeat(count);
    }
    return output;
  },

  //判断输入的时间是否是该月的最后一天
  isLastDayOfMonth(date) {
    date = new Date(date)
    const year = date.getFullYear();
    const month = date.getMonth();
    const nextMonth = month + 1;
    const nextMonthDate = new Date(year, nextMonth, 0);
    return date.getDate() === nextMonthDate.getDate();
  },

  //算出传入的时间再该月还剩下多少天
  getRemainingDaysInMonth(date) {
    date = new Date(date)
    const year = date.getFullYear();
    const month = date.getMonth();
    const lastDayOfMonth = new Date(year, month + 1, 0).getDate();
    const currentDay = date.getDate();
    const remainingDays = lastDayOfMonth - currentDay;
    return remainingDays;
  },

  //写一个方法获取2023-08-01到2024-01-05两个日期之间的全部日期
  getDatesBetween(startDate, endDate) {
    const dates = [];
    const start = new Date(startDate);
    const end = new Date(endDate);

    while (start <= end) {
      dates.push(start.toISOString().split('T')[0]);
      start.setDate(start.getDate() + 1);
    }
    return dates;
  },

  //判断输入的日期是否是这个月的1号
  isFirstDayOfMonth(dateString) {
    const date = new Date(dateString);
    return date.getDate() === 1;
  },

  //把合同的开始日期2023-07-13到结束日期2026-07-12按照3个月一期进行分割
  splitContract(startDate, endDate, interval) {
    const result = [];
    const start = new Date(startDate);
    const end = new Date(endDate);

    while (start <= end) {
      const periodStart = new Date(start);
      const periodEnd = new Date(start);
      periodEnd.setMonth(periodEnd.getMonth() + interval);
      periodEnd.setDate(periodEnd.getDate() - 1);
      result.push({
        start: this.dateTimeFormateFn(periodStart.toLocaleDateString()),
        end: this.dateTimeFormateFn(periodEnd.toLocaleDateString())
      });
      start.setMonth(start.getMonth() + interval);
    }
    return result;
  },

  //输入开始时间2023-07-13和结束时间2023-10-12，罗列出这里涉及到的月份，例如得到结果[2023-07，2023-08，2023-09，2023-10]
  getMonths(startDate, endDate) {
    const start = new Date(startDate);
    const end = new Date(endDate);
    const months = [];
    // 循环遍历每个月份，将其格式化为 'YYYY-MM' 并添加到结果数组中
    let currentDate = start;
    while (currentDate <= end) {
      const formattedMonth = currentDate.toISOString().slice(0, 7);
      months.push(formattedMonth);
      // 将当前日期设置为下一个月的第一天
      currentDate.setMonth(currentDate.getMonth() + 1);
      currentDate.setDate(1);
    }
    return months;
  },

  //传入2023-07,判断这个月一共多少天
  getDaysInMonth(dateString) {
    const date = new Date(dateString);
    // 将日期设置为下个月的第一天
    date.setMonth(date.getMonth() + 1);
    date.setDate(1);
    // 倒退一天并获取日期，即当前月份的最后一天
    date.setDate(date.getDate() - 1);
    return date.getDate();
  },

  //获取日期前n天的日期
  getPreviousDates(dateString, days) {
    const dates = [];
    const currentDate = new Date(dateString);
    for (let i = 0; i < days; i++) {
      const previousDate = new Date(currentDate.getTime() - i * 24 * 60 * 60 * 1000);
      const formattedDate = previousDate.toISOString().split('T')[0];
      dates.push(formattedDate);
    }
    return dates;
  },


  //导入的excel转成数据
  fileToJson(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: "array" });
          const worksheet = workbook.Sheets[workbook.SheetNames[0]];
          const json = XLSX.utils.sheet_to_json(worksheet, { header: 1, raw: false, defval: "" });
          resolve(json);
        } catch (err) {
          reject(err);
        }
      }; // 成功回调
      reader.onerror = (err) => {
        reject(err);
      }; // 失败回调
      reader.readAsArrayBuffer(file);
    });
  },

  //json数据转excel
  exportToExcel(data, excelName) {
    //data  jsonData:数据  cols:表头样式   rows:文本居中
    const worksheet = XLSX.utils.json_to_sheet(data.jsonData);// 创建一个工作表
    if (data.cols) worksheet['!cols'] = data.cols
    if (data.rows) worksheet['!rows'] = data.rows
    const workbook = XLSX.utils.book_new(); // 创建一个工作簿
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');// 将工作表添加到工作簿
    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const fileName = `${excelName}.xlsx`;
    if (navigator.msSaveBlob) {
      navigator.msSaveBlob(blob, fileName);
    } else {
      const link = document.createElement('a');
      if (link.download !== undefined) {
        const url = URL.createObjectURL(blob);
        link.setAttribute('href', url);
        link.setAttribute('download', fileName);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    }
  },

  //js 小数点保留两位，第二位向上进一位
  roundedNum(num) {
    if (!num) num = 0
    return Number.isInteger(num) ? num : Math.ceil(num * 100) / 100;
  },

  //字符串超过多少位就显示省略号
  truncateString(str, maxLength) {
    if (!str) return
    if (str.length > maxLength) {
      return str.substring(0, maxLength) + '...';
    } else {
      return str;
    }
  },

  //element plus ElMessage
  showToast(message, type) {
    let a
    switch (type) {
      case 0:
        a = "error"
        break;
      case 1:
        a = "warning"
        break;
      default:
        a = "success"
        break;
    }
    ElMessage({ message, type: a })
  },

  //json数组里面的某一个字段是否等于一个变量
  isFieldEqual(arr, field, value) {
    return arr.some(item => item[field] == value);
  },

  //数组里面的某一个字段等于一个变量，则返回数组里面他对应的下标
  findIndexByField(arr, field, value) {
    return arr.findIndex(item => item[field] == value);
  },

  //两个json数组，如果两个json数组里面的某一个字段是相同的，则提取出来组成新数组
  extractCommonField(arr1, arr2, field) {
    const result = [];
    for (let obj1 of arr1) {
      for (let obj2 of arr2) {
        if (obj1[field] === obj2[field]) {
          result.push(obj1);
        }
      }
    }
    return result;
  },

  //复制
  copy(href) {
    navigator.clipboard.writeText(href).then(() => {
      this.showToast("复制成功");
    }).catch((error) => {
      this.showToast(`复制失败:${error}`, 0);
    });
  },

  // 下载网络图片
  async downloadImage(imgUrl, title) {
    // 获取图片对象和画布对象
    const response = await fetch(imgUrl)
    const blob = await response.blob()
    // 创建下载链接
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = title ? title : 'image.png'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    // 释放 Blob URL
    window.URL.revokeObjectURL(url)
  },

  //传入id和parentId，如果parentId=别人的id，则加到别人的children里面
  transformArray(arr, id, pid) {
    const map = {};
    const roots = [];
    arr.forEach(item => {
      map[item[id]] = { ...item, children: [] };
    });
    arr.forEach(item => {
      if (item[pid] && map[item[pid]]) {
        map[item[pid]].children.push(map[item[id]]);
      } else {
        roots.push(map[item[id]]);
      }
    });
    return roots;
  },

  //判断url是否是http或https 
  isHttp(url) {
    return url.includes('http://') || url.includes('https://')
  },

  //blobToFile
  blobToFile(blob, fileName) {
    const file = new File([blob], fileName, { type: blob.type });
    return file;
  },

  //判断字符串里面是否包含中文
  hasChinese(str) {
    const pattern = /[\u4E00-\u9FA5]/; // 匹配中文字符的正则表达式
    return pattern.test(str);
  },

  //将字符串里面的中文提取出来
  getChineseCharacters(str) {
    const chineseRegex = /[\u4e00-\u9fa5]/g; // 匹配中文字符的正则表达式
    const chineseCharacters = str.match(chineseRegex); // 使用正则表达式匹配中文字符
    return chineseCharacters;
  },

  //json 数组按照某一个字段排序
  sortItems(items, sortOrder, field) {
    return items
      .sort((a, b) => {
        if (sortOrder === "asc") {
          return a[field] - b[field];
        } else {
          return b[field] - a[field];
        }
      })
      .map((item) => {
        if (item.children) {
          item.children = this.sortItems(item.children, sortOrder, field);
        }
        return item;
      });
  },

  //判断是不是线上链接是不是图片
  async isImageUrl(url) {
    try {
      const response = await fetch(url, { method: 'HEAD' })
      const contentType = response.headers.get('content-type')
      return contentType.includes('image/')
    } catch (error) {
      return false // 请求失败，或者无法获取 Content-Type 头信息
    }
  },

  //根据数据条数与每页多少条数据计算页数
  pageCount(totalItems, itemsPerPage) {
    return Math.ceil(totalItems / itemsPerPage);
  },

  //判断是不是 json
  isJSON(str) {
    try {
      JSON.parse(str);
      return true;
    } catch (e) {
      return false;
    }
  },

  //将字符串金额转成数字金额，保留两位小数
  formatNumber(numStr) {
    const num = parseFloat(numStr);
    if (isNaN(num)) return numStr;

    // 分离整数和小数部分
    const parts = num.toString().split('.');
    const integerPart = parts[0];

    // 使用正则表达式添加千位分隔符
    return integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  },


  //根据字符串生成随机颜色
  getColor(value) {
    return "#" + getHashCode(value).toString(16).substr(0, 6)

    function getHashCode(str) {
      var hash = 1315423911, i, ch;
      for (i = str.length - 1; i >= 0; i--) {
        ch = str.charCodeAt(i);
        hash ^= ((hash << 5) + ch + (hash >> 2));
      }
      return (hash & 0x7FFFFFFF);
    }
  },

  //传入日期，判断是周几
  getDayOfWeek(date) {
    date = new Date(date);
    const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    return days[date.getDay()];
  },

  //判断变量的数据类型
  isJsonArray(variable) {
    if (typeof variable === "string") {
      return "string";
    } else if (Array.isArray(variable)) {
      // 进一步判断是否为JSON数组
      let isJsonArray = variable.every(item => typeof item === "object" && item !== null && Object.keys(item).length > 0);
      if (isJsonArray) {
        return "jsonArr";
      } else {
        return "arr";
      }
    } else {
      return "not a string, array, or json array";
    }
  },

  //传入一个数组，和两个key，根据这两个key来进行去重
  uniqueByFields(arr, field1, field2) {
    const seen = new Set();
    return arr.filter(item => {
      const key = `${item[field1]}_${item[field2]}`; // 创建唯一键
      if (seen.has(key)) {
        return false; // 如果已经存在，则过滤掉
      }
      seen.add(key); // 否则添加到 Set 中
      return true; // 保留该项
    });
  },

  //传入两个数组，取不同的值组成新数组
  getDifferentValues(arr1, arr2) {
    // 过滤出 arr1 中不在 arr2 中的值
    const uniqueToArr1 = arr1.filter(item => !arr2.includes(item));
    // 过滤出 arr2 中不在 arr1 中的值
    const uniqueToArr2 = arr2.filter(item => !arr1.includes(item));
    // 合并两个结果
    return uniqueToArr1.concat(uniqueToArr2);
  },
}
